package play.modules.plovr;

import com.sun.net.httpserver.Headers;
import com.sun.net.httpserver.HttpContext;
import com.sun.net.httpserver.HttpExchange;
import com.sun.net.httpserver.HttpPrincipal;
import play.mvc.Http;

import java.io.*;
import java.net.InetSocketAddress;
import java.net.URI;
import java.nio.charset.Charset;
import java.util.Map;

/**
 * Mostly-stubbed-out HttpExchange to send to CompileRequestHandler and InputFileHandler
 * author: Dallan Quass
 */
public class DummyHttpExchange extends HttpExchange {
   private ByteArrayOutputStream baos;
   private Http.Request request;
   private String requestProtocol;
   private Headers requestHeaders;
   private Headers responseHeaders;
   private int responseCode;

   public DummyHttpExchange(Http.Request request) {
      super();
      // FIXME? how to get protocol from request - is it necessary?
      this.requestProtocol = "http";
      this.request = request;
      this.requestHeaders = new Headers();
      for (String key : request.headers.keySet()) {
         Http.Header value = request.headers.get(key);
         if ("referer".equals(key)) {
            key = "Referer"; // Play must lowercase the headers; plovr doesn't expect that
         }
         this.requestHeaders.put(key, value.values);
      }
      this.responseHeaders = new Headers();
      this.baos = new ByteArrayOutputStream();
   }

   public String getResponseBodyAsString(Charset charset) throws UnsupportedEncodingException {
      return baos.toString(charset.name());
   }

   @Override
   public Headers getRequestHeaders() {
      return requestHeaders;
   }

   @Override
   public Headers getResponseHeaders() {
      return responseHeaders;
   }

   @Override
   public URI getRequestURI() {
      String uri = String.format("%s://%s%s", requestProtocol, request.host, request.url);
      return URI.create(uri);
   }

   @Override
   public String getRequestMethod() {
      return request.method;
   }

   @Override
   public HttpContext getHttpContext() {
      play.Logger.error("getHttpContext");
      return null;
   }

   @Override
   public void close() {
      try {
         baos.close();
      } catch (IOException e) {
         play.Logger.error("error closing stream: ");
         e.printStackTrace();
      }
   }

   @Override
   public InputStream getRequestBody() {
      play.Logger.error("getRequestBody");
      return null;
   }

   @Override
   public OutputStream getResponseBody() {
      return baos;
   }

   @Override
   public void sendResponseHeaders(int i, long l) throws IOException {
      this.responseCode = i;
   }

   @Override
   public InetSocketAddress getRemoteAddress() {
      play.Logger.error("getRemoteAddress");
      return null;
   }

   @Override
   public int getResponseCode() {
      return this.responseCode;
   }

   @Override
   public InetSocketAddress getLocalAddress() {
      play.Logger.error("getLocalAddress");
      return null;
   }

   @Override
   public String getProtocol() {
      return requestProtocol;
   }

   @Override
   public Object getAttribute(String s) {
      play.Logger.error("getAttribute="+s);
      return null;
   }

   @Override
   public void setAttribute(String s, Object o) {
      play.Logger.error("setAttribute "+s+" = "+o.toString());
   }

   @Override
   public void setStreams(InputStream inputStream, OutputStream outputStream) {
      play.Logger.error("setStreams");
   }

   @Override
   public HttpPrincipal getPrincipal() {
      play.Logger.error("getPrincipal");
      return null;
   }
}
